package com.abel.bigwater.data.mapper

import com.abel.bigwater.data.jnrq.JnrqDevice
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query
import org.springframework.stereotype.Component

@Component
class DeviceTemplate {
    @Autowired
    var template: MongoTemplate? = null

    @Value("\${anji.firmId}")
    var firmId: String? = null

    fun findJnrqDevice(addr: String): JnrqDevice? {
        try {
            return template!!.find(Query.query(Criteria.where("firmId").regex("$firmId\\d*")
                    .and("address").`is`(addr)),
                    JnrqDevice::class.java).firstOrNull()
        } catch (ex: Exception) {
            lgr.error("fail to find device: ${ex.message}", ex)
            return null
        }
    }

    fun findJnrqDeviceByMeter(_meterCode: String): JnrqDevice? {
        var cr = Criteria.where("firmId").regex("$firmId\\d*")
                .and("meterCode").`is`(_meterCode)

        try {
            return template!!.find(Query.query(cr), JnrqDevice::class.java).firstOrNull()
        } catch (ex: Exception) {
            lgr.error("fail to find device: ${ex.message}", ex)
            return null
        }
    }

    fun findJnrqDeviceList(): List<JnrqDevice> {
        return template!!.find(Query.query(Criteria.where("firmId").regex("$firmId\\d*")),
                JnrqDevice::class.java)
    }

    fun insertJnrqDevice(dev: JnrqDevice): JnrqDevice {
        if (dev.address.isNullOrBlank()) throw IllegalArgumentException("address can't be null")
        if (!dev.firmId.orEmpty().startsWith(firmId!!)) {
            dev.firmId = firmId
        }

        return template!!.insert(dev)
    }

    fun removeJnrqDevice(dev: JnrqDevice): JnrqDevice? {
        val dr = template!!.remove(Query.query(Criteria.where(KEY_FIRMID).`is`(dev.firmId)
                .and(KEY_ADDRESS).`is`(dev.address)), JnrqDevice::class.java)
        return if (dr.deletedCount == 1L) {
            dev
        } else null
    }

    companion object {
        private val lgr = LoggerFactory.getLogger(DeviceTemplate::class.java)

        const val KEY_FIRMID = "firmId"
        const val KEY_ADDRESS = "address"
    }
}